home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / network / base / net-tool.32- / net-tool / net-tools-1.32-alpha / rarp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-17  |  6.0 KB  |  281 lines

  1. /*
  2.  * rarp        This file contains an implementation of the command
  3.  *        that maintains the kernel's RARP cache.  It is derived
  4.  *              from Fred N. van Kempen's arp command.
  5.  *
  6.  * Usage:       rarp -d hostname                      Delete entry
  7.  *        rarp -s hostname ethernet_address     Add entry
  8.  *              rarp -a                               Print entries
  9.  *
  10.  *  Ross D. Martin  <martin@trcsun3.eas.asu.edu>
  11.  * 
  12.  * THIS NEEDS TO BE CLEANED UP COMPLETELY           -eckes
  13.  */
  14. #include <sys/types.h>
  15. #include <sys/socket.h>
  16. #include <sys/ioctl.h>
  17. #include <netinet/in.h>
  18. #include <arpa/inet.h>
  19. #include <netinet/in.h>
  20. #include <net/if.h>
  21. #include <linux/netdevice.h>
  22. #include <linux/if_arp.h>
  23. #include <stdlib.h>
  24. #include <stdio.h>
  25. #include <errno.h>
  26. #include <fcntl.h>
  27. #include <netdb.h>
  28. #include <string.h>
  29. #include <unistd.h>
  30. #include "config.h"
  31. #include "net-locale.h"
  32.  
  33. int sockfd;                /* active socket descriptor    */
  34.  
  35. /* Input an Ethernet address and convert to binary. */
  36. unsigned char *in_ether(char *ptr)
  37. {
  38.   static unsigned char buff[6];
  39.   unsigned int temp[6];
  40.   int num;
  41.  
  42.   num=sscanf(ptr,"%x:%x:%x:%x:%x:%x",
  43.          &temp[0],&temp[1],&temp[2],&temp[3],&temp[4],&temp[5]);
  44.   if(num!=6)
  45.     {
  46.       fprintf(stderr,NLS_CATGETS(catfd, rarpSet, rarp_invalid, "Invalid Ethernet address: %s\n"), ptr);
  47.     }
  48.   
  49.   for(num=0;num<6;num++)
  50.     buff[num]=temp[num];
  51.  
  52.   return(buff);
  53. }
  54.  
  55.  
  56. /* This structure defines hardware protocols and their handlers. */
  57. struct hwtype {
  58.   char        *name;
  59.   int        type;
  60.   int        hlen;
  61.   unsigned char    *(*input)(char *);
  62. };
  63.  
  64. struct hwtype hwtypes[] = {
  65.   { "ether",  ARPHRD_ETHER,  6, in_ether  },
  66. #if HAVE_ARPHRD_PRONET /* XXX */
  67.   { "pronet", ARPHRD_PRONET, 2, in_pronet },
  68. #endif
  69. #if HAVE_ARPHRD_AX25 /* XXX */
  70.   { "ax25",   ARPHRD_AX25,  12, in_ax25   },
  71. #endif
  72.   { NULL,     -1,            0, NULL      }
  73. };
  74.  
  75. struct hwtype *hardware;
  76.  
  77. /* Check our hardware type table for this type. */
  78. struct hwtype *get_type(char *name)
  79. {
  80.   register struct hwtype *hwp;
  81.  
  82.   hwp = hwtypes;
  83.   while (hwp->name != NULL) {
  84.     if (!strcmp(hwp->name, name)) return(hwp);
  85.     hwp++;
  86.   }
  87.   return(NULL);
  88. }
  89.  
  90.  
  91. /* Check our hardware type table for this type. */
  92. struct hwtype *get_ntype(int type)
  93. {
  94.   register struct hwtype *hwp;
  95.  
  96.   hwp = hwtypes;
  97.   while (hwp->name != NULL) {
  98.     if (hwp->type == type) return(hwp);
  99.     hwp++;
  100.   }
  101.   return(NULL);
  102. }
  103.  
  104.  
  105. /* Delete an entry from the ARP cache. */
  106. int arp_del(char *host)
  107. {
  108.   struct hostent *hp;
  109.   struct arpreq req;
  110.   struct sockaddr_in *si;
  111.   register int i;
  112.   int found;
  113.  
  114.   /* Resolve the host name. */
  115.   if ((hp = gethostbyname(host)) == NULL) {
  116.     fprintf(stderr, NLS_CATGETS(catfd, rarpSet, rarp_unkn_host, "rarp: %s: unknown host\n"), host);
  117.     return(-1);
  118.   }
  119.  
  120.   /* The host can have more than one address, so we loop on them. */
  121.   i = -1;
  122.   found = 0;
  123.   while (hp->h_addr_list[++i] != NULL) {
  124.     memset((char *) &req, 0, sizeof(req));
  125.     si = (struct sockaddr_in *) &req.arp_pa;
  126.     si->sin_family = hp->h_addrtype;
  127.     memcpy((char *) &si->sin_addr, hp->h_addr_list[i], hp->h_length);
  128.  
  129.     /* Call the kernel. */
  130.     if (ioctl(sockfd, SIOCDRARP, &req) < 0) {
  131.         if (errno != ENXIO) {
  132.             perror("SIOCDRARP");
  133.             return(-1);
  134.         } else continue;
  135.     }
  136.     found++;
  137.   }
  138.  
  139.   if (found == 0) printf(NLS_CATGETS(catfd, rarpSet, rarp_noentry, "No ARP entry for %s\n"), hp->h_name);
  140.   return(0);
  141. }
  142.  
  143.  
  144. /* Set an entry in the ARP cache. */
  145. int arp_set(char *host, char *hw_addr)
  146. {
  147.   struct hostent *hp;
  148.   struct arpreq req;
  149.   struct sockaddr_in *si;
  150.   unsigned char *ha;
  151.  
  152.   /* Resolve the host name. */
  153.   if ((hp = gethostbyname(host)) == NULL) {
  154.     fprintf(stderr, NLS_CATGETS(catfd, rarpSet, rarp_unkn_host, "rarp: %s: unknown host\n"), host);
  155.     return(-1);
  156.   }
  157.  
  158.   if ((ha = hardware->input(hw_addr)) == NULL) return(-1);
  159.  
  160.   /* Clear and fill in the request block. */
  161.   memset((char *) &req, 0, sizeof(req));
  162.   si = (struct sockaddr_in *) &req.arp_pa;
  163.   si->sin_family = hp->h_addrtype;
  164.   memcpy((char *) &si->sin_addr, hp->h_addr_list[0], hp->h_length);
  165.   req.arp_ha.sa_family = hardware->type;
  166.   memcpy(req.arp_ha.sa_data, ha, hardware->hlen);
  167.  
  168.   /* Call the kernel. */
  169.   if (ioctl(sockfd, SIOCSRARP, &req) < 0) {
  170.     perror("SIOCSRARP");
  171.     return(-1);
  172.   }
  173.   return(0);
  174. }
  175.  
  176.  
  177. static void usage(void)
  178. {
  179.   fprintf(stderr, NLS_CATGETS(catfd, rarpSet, rarp_usage1,
  180.       "Usage: rarp -a                   List entries in cache.\n"));
  181.   fprintf(stderr, NLS_CATGETS(catfd, rarpSet, rarp_usage2,
  182.       "       rarp -d hostname          Delete hostname from cache.\n"));
  183.   fprintf(stderr, NLS_CATGETS(catfd, rarpSet, rarp_usage3,
  184.       "       rarp -s hostname hw_addr  Add hostname to cache.\n"));
  185.   NLS_CATCLOSE(catfd)
  186.   exit(-1);
  187. }
  188.  
  189.  
  190. void main(argc, argv)
  191. int argc;
  192. char **argv;
  193. {
  194.   int result=0;
  195.  
  196. #if NLS
  197.   setlocale (LC_MESSAGES, "");
  198.   catfd = catopen ("nettools", MCLoadBySet);
  199. #endif
  200.  
  201.   /* Initialize variables... */
  202.   hardware = get_type("ether");
  203.  
  204.   argv++;
  205.   argc--;
  206.   if(argc==0)
  207.     usage();
  208.  
  209.  /* Fetch the command-line arguments. */
  210.  
  211.   if(argv[0][0]!='-')
  212.     usage();
  213.  
  214.   if(argv[0][1]=='t')
  215.     {
  216.       if(argc<3)  /* Need -t, type, and then at least one further arg */
  217.     usage();
  218.       
  219.       hardware = get_type(argv[1]);
  220.       if (hardware->type == -1) 
  221.     {
  222.       fprintf(stderr, NLS_CATGETS(catfd, rarpSet, rarp_unkn_hw,
  223.           "rarp: %s: unknown hardware type.\n"), optarg);
  224.       NLS_CATCLOSE(catfd)
  225.       exit(-1);
  226.     }
  227.       argv+=2;
  228.       argc-=2;
  229.  
  230.       if(argv[0][0]!='-')
  231.     usage();
  232.     }
  233.  
  234.   switch(argv[0][1]) 
  235.     {
  236.     case 'a':
  237.       if(argc!=1)
  238.     usage();
  239.       result=system("cat /proc/net/rarp");  /* This is lazy, but who cares? */
  240.       break;
  241.  
  242.     case 'd':
  243.       if(argc!=2)
  244.     usage();
  245.  
  246.       if ((sockfd = socket(AF_INET,SOCK_DGRAM,0)) <0)
  247.     {
  248.       perror("socket");
  249.       NLS_CATCLOSE(catfd)
  250.       exit(-1);
  251.     }
  252.  
  253.       result = arp_del(argv[1]);
  254.  
  255.       (void) close(sockfd);
  256.       break;
  257.  
  258.     case 's':
  259.       if(argc!=3)
  260.     usage();
  261.  
  262.       if ((sockfd = socket(AF_INET,SOCK_DGRAM,0)) <0)
  263.     {
  264.       perror("socket");
  265.       NLS_CATCLOSE(catfd)
  266.       exit(-1);
  267.     }
  268.       result = arp_set(argv[1],argv[2]);
  269.  
  270.       (void) close(sockfd);
  271.       break;
  272.  
  273.     default:
  274.       usage();
  275.   }
  276.  
  277.   NLS_CATCLOSE(catfd)
  278.   exit(result);
  279. }
  280.  
  281.